﻿using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Drawing.Design;
using System.Linq;
using System.Windows.Forms;
using static System.Windows.Forms.CheckedListBox;

#pragma warning disable IDE0130 // 命名空间与文件夹结构不匹配
namespace zykControl
#pragma warning restore IDE0130 // 命名空间与文件夹结构不匹配
{
    /// <summary>带复选框的下拉列表</summary>
    public class CheckedComboBox : Button
    {
        /// <summary>带复选框的下拉列表</summary>
        public CheckedComboBox()
        {
            MouseUp += CheckedComboBox_MouseUp;
            Leave += CheckedComboBox_Leave;
            HandleCreated += CheckedComboBox_HandleCreated;
        }

        private readonly FrmCheckedComboBoxDrop mDropFrom = new();
        internal bool CloseAsync;

        private void CheckedComboBox_MouseUp(object? sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
                return;
            if (mDropFrom.Visible)
            {
                mDropFrom.Hide();
            }
            else
            {
                mDropFrom.ShowA(this);
            }
        }

        private void CheckedComboBox_Leave(object? sender, EventArgs e)
        {
            mDropFrom.Hide();
        }

        private void FormClick(object? sender, EventArgs e)
        {
            if (ReferenceEquals(sender, FindForm()))
                mDropFrom.Hide();
        }

        private void CheckedComboBox_HandleCreated(object? sender, EventArgs e)
        {
            if (DesignMode == false) FindForm()!.Click += FormClick;
            if (DesignMode == false) FindForm()!.MouseDown += FormClick;
            if (DesignMode == false) FindForm()!.Move += FormClick;
        }

        /// <summary>控件的字体</summary>
        [AllowNull]
        public override Font Font
        {
            get
            {
                return base.Font;
            }
            set
            {
                mDropFrom.Font = value;
                base.Font = value;
            }
        }

        /// <summary>
        /// 项列表
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
        [Localizable(true)]
        public ObjectCollection Items
        {
            get
            {
                return mDropFrom.CheckedListBox1.Items;
            }
        }

        private string mValue = "";

        /// <summary>
        /// 获取/设置 选中的文本
        /// </summary>
        public string Value
        {
            get
            {
                return mValue;
            }

            set
            {
                mValue = value;
                if (CloseAsync)
                    return;
                RefreshCheckedComboBoxSelection();
            }
        }

        /// <summary>
        /// 返回选中的项的索引/设置指定索引的项被选中
        /// </summary>
        public int SelectedIndex
        {
            get
            {
                return mDropFrom.CheckedListBox1.SelectedIndex;
            }

            set
            {
                mDropFrom.CheckedListBox1.SelectedIndex = value;
            }
        }

        /// <summary>
        /// 文本内容改变时被触发
        /// </summary>
        /// <param name="e"></param>
        protected override void OnTextChanged(EventArgs e)
        {
            CloseAsync = true;
            RefreshCheckedComboBoxSelection();
            CloseAsync = false;
            base.OnTextChanged(e);
        }

        /// <summary>
        /// 刷新列表选中项并返回可视文本
        /// </summary>
        internal void RefreshCheckedComboBoxSelection()
        {
            var dArray = Value.Split([','], StringSplitOptions.RemoveEmptyEntries);
            string dDisplayLine = "";
            for (int xx = 0, loopTo = mDropFrom.CheckedListBox1.Items.Count - 1; xx <= loopTo; xx++)
            {
                var dItemObject = mDropFrom.CheckedListBox1.Items[xx];
                string dKey = "";
                string dDisplayText = "";
                if (dItemObject is CheckedComboBoxItem item)
                {
                    dKey = item.Key ?? "";
                    dDisplayText = item.Description ?? "";
                }
                else if (dItemObject is string || dItemObject is ValueType || string.IsNullOrEmpty(ValueMember) || string.IsNullOrEmpty(DisplayMember))
                {
                    dKey = dItemObject.ToString() ?? "";
                    dDisplayText = dItemObject.ToString() ?? "";
                }
                else if (dItemObject.GetType().GetProperty(ValueMember) is not null && dItemObject.GetType().GetProperty(DisplayMember) is not null)
                {
                    try
                    {
                        dKey = dItemObject.GetType().GetProperty(mDropFrom.CheckedListBox1.ValueMember)?.GetValue(dItemObject, null)?.ToString() ?? "";
                        dDisplayText = dItemObject.GetType().GetProperty(mDropFrom.CheckedListBox1.DisplayMember)?.GetValue(dItemObject, null)?.ToString() ?? "";
                    }
                    catch (Exception)
                    {
                    }
                }
                else
                {
                    dKey = dItemObject.ToString() ?? "";
                    dDisplayText = dItemObject.ToString() ?? "";
                }

                var dItem = dArray.FirstOrDefault(i => (i.Trim() ?? "") == dKey);
                if (dItem is null)
                {
                    mDropFrom.CheckedListBox1.SetItemChecked(xx, false);
                }
                else
                {
                    mDropFrom.CheckedListBox1.SetItemChecked(xx, true);
                    dDisplayLine += dDisplayText + ",";
                }
            }

            if (dDisplayLine.Length > 0)
                dDisplayLine = dDisplayLine[..^1];
            SelectedIndex = -1;
            Text = dDisplayLine;
        }

        /// <summary>
        /// 返回/设置 绑定列表项的显示成员
        /// </summary>
        public string DisplayMember
        {
            get
            {
                return mDropFrom.CheckedListBox1.DisplayMember;
            }

            set
            {
                mDropFrom.CheckedListBox1.DisplayMember = value;
            }
        }

        /// <summary>
        /// 返回/设置 绑定列表项的值成员
        /// </summary>
        public string ValueMember
        {
            get
            {
                return mDropFrom.CheckedListBox1.ValueMember;
            }

            set
            {
                mDropFrom.CheckedListBox1.ValueMember = value;
            }
        }

        //private void InitializeComponent()
        //{
        //    SuspendLayout();
        //    // 
        //    // CheckedComboBox
        //    // 
        //    ImageAlign = ContentAlignment.MiddleLeft;
        //    ResumeLayout(false);
        //}
    }
}